<template>
  <div class="awl">
    <div ref="vtkContainer" />
    <table class="controls">
      <tbody>
        <tr>
          <td>
            <select style="width: 80%; height: 25px" :value="representation" @change="setRepresentation($event.target.value)">
              <option value="0">Points</option>
              <option value="1">Wireframe</option>
              <option value="2">Surface</option>
            </select>
          </td>
          <td>
            <input type="range" min="4" max="80" :value="coneResolution" @input="setConeResolution($event.target.value)" />
          </td>
        </tr>
        <tr>
          <td>Height</td>
          <td>
            <input type="range" min="0.5" max="2.0" step="0.1" :value="height" @input="changeHeight($event.target.value)" />
          </td>
        </tr>
        <tr>
          <td>Radius</td>
          <td>
            <input type="range" min="0.5" max="2.0" step="0.1" :value="radius" @input="changeRadius($event.target.value)" />
          </td>
        </tr>
        <tr>
          <td>Capping</td>
          <td>
            <input type="checkbox" :checked="capping" @change="changeCapping($event.target.checked)" />
          </td>
        </tr>
        <tr style="text-align: center;">
          <td></td>
          <td>X</td>
          <td>Y</td>
          <td>Z</td>
        </tr>
        <tr>
          <td>Origin</td>
          <td>
            <input
              style="width: 90px"
              class="center"
              data-index="0"
              type="range"
              min="-1"
              max="1"
              step="0.1"
              :value="oX"
              @input="changeOx($event.target.value)"
            />
          </td>
          <td>
            <input
              style="width: 60px"
              class="center"
              data-index="1"
              type="range"
              min="-1"
              max="1"
              step="0.1"
              :value="oY"
              @input="changeOy($event.target.value)"
            />
          </td>
          <td>
            <input
              style="width: 60px"
              class="center"
              data-index="2"
              type="range"
              min="-1"
              max="1"
              step="0.1"
              :value="oZ"
              @input="changeOz($event.target.value)"
            />
          </td>
        </tr>
        <tr>
          <td>Direction</td>
          <td>
            <input
              style="width: 90px"
              class="center"
              data-index="0"
              type="range"
              min="-1"
              max="1"
              step="0.1"
              :value="dX"
              @input="changeDx($event.target.value)"
            />
          </td>
          <td>
            <input
              style="width: 60px"
              class="center"
              data-index="1"
              type="range"
              min="-1"
              max="1"
              step="0.1"
              :value="dY"
              @input="changeDy($event.target.value)"
            />
          </td>
          <td>
            <input
              style="width: 60px"
              class="center"
              data-index="2"
              type="range"
              min="-1"
              max="1"
              step="0.1"
              :value="dZ"
              @input="changeDz($event.target.value)"
            />
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import { ref, unref, onMounted, onBeforeUnmount, watchEffect } from 'vue'

import '@kitware/vtk.js/Rendering/Profiles/Geometry'

import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow'

import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper'
import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource'

export default {
  // name: 'VtkScene',

  setup() {
    const vtkContainer = ref(null)
    const context = ref(null)
    const coneResolution = ref(6)
    const representation = ref(2)
    const height = ref(0.5)
    const radius = ref(0.5)
    const capping = ref(true)
    const oX = ref(0)
    const oY = ref(0)
    const oZ = ref(0)
    const dX = ref(0)
    const dY = ref(0)
    const dZ = ref(0)

    function setConeResolution(res) {
      coneResolution.value = Number(res)
    }

    function setRepresentation(rep) {
      representation.value = Number(rep)
    }
    function changeHeight(h) {
      console.log(h)
      height.value = Number(h)
    }
    function changeRadius(r) {
      console.log(r)
      radius.value = Number(r)
    }
    function changeCapping(c) {
      console.log(c)
      capping.value = c
    }
    function changeOx(x) {
      oX.value = Number(x)
    }
    function changeOy(y) {
      oY.value = Number(y)
    }
    function changeOz(z) {
      oZ.value = Number(z)
    }
    function changeDx(x) {
      dX.value = Number(x)
    }
    function changeDy(y) {
      dY.value = Number(y)
    }
    function changeDz(z) {
      dZ.value = Number(z)
    }
    watchEffect(() => {
      const res = unref(coneResolution)
      const rep = unref(representation)
      const h = unref(height)
      const r = unref(radius)
      const c = unref(capping)
      const ox = unref(oX)
      const oy = unref(oY)
      const oz = unref(oZ)
      const dx = unref(dX)
      const dy = unref(dY)
      const dz = unref(dZ)
      if (context.value) {
        const { actor, coneSource, renderWindow } = context.value
        coneSource.setResolution(res)
        coneSource.setHeight(h)
        coneSource.setRadius(r)
        coneSource.setCapping(c)
        coneSource.setCenter(ox, oy, oz)
        coneSource.setDirection(dx, dy, dz)
        actor.getProperty().setRepresentation(rep)
        renderWindow.render()
      }
    })

    onMounted(() => {
      if (!context.value) {
        const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
          rootContainer: vtkContainer.value
        })
        const coneSource = vtkConeSource.newInstance({ height: 1.0 })

        const mapper = vtkMapper.newInstance()
        mapper.setInputConnection(coneSource.getOutputPort())

        const actor = vtkActor.newInstance()
        actor.setMapper(mapper)

        const renderer = fullScreenRenderer.getRenderer()
        const renderWindow = fullScreenRenderer.getRenderWindow()

        renderer.addActor(actor)
        renderer.resetCamera()
        renderWindow.render()

        context.value = {
          fullScreenRenderer,
          renderWindow,
          renderer,
          coneSource,
          actor,
          mapper
        }
      }
    })

    onBeforeUnmount(() => {
      if (context.value) {
        const { fullScreenRenderer, coneSource, actor, mapper } = context.value
        actor.delete()
        mapper.delete()
        coneSource.delete()
        fullScreenRenderer.delete()
        context.value = null
      }
    })

    return {
      height,
      radius,
      capping,
      oX,
      oY,
      oZ,
      dX,
      dY,
      dZ,
      changeHeight,
      changeRadius,
      changeCapping,
      changeOx,
      changeOy,
      changeOz,
      changeDx,
      changeDy,
      changeDz,

      vtkContainer,
      setRepresentation,
      setConeResolution,
      coneResolution,
      representation
    }
  }
}
</script>

<style scoped>
.awl {
  margin: 0px;
  padding: 0px;
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  overflow: hidden;
  cursor: pointer;
  touch-action: none;
  user-select: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.controls {
  position: absolute;
  left: 25px;
  top: 25px;
  background-color: white;
  border-radius: 5px;
  list-style: none;
  padding: 5px 10px;
  margin: 0px;
  display: block;
  border: 1px solid black;
  max-width: calc(100% - 70px);
  max-height: calc(100% - 60px);
  overflow: auto;
}
</style>
